﻿using System.Collections.Generic;
using UnityEngine;

namespace Jinndev {

    public class DynamicData : MonoBehaviour {

        public enum ValueType {
            String,
            Boolean,
            Integer,
            Float,
            Vector2,
            Vector3,
            Color,
            Object,
        }

        [System.Serializable]
        public class DataPair {
            [Tooltip("键名")]
            public string key;
            [Tooltip("值类型")]
            public ValueType valueType;
            [Tooltip("注释(可选)")]
            public string comment;

            public string valueString;
            public bool valueBoolean;
            public int valueInteger;
            public float valueFloat;
            public Vector2 valueVector2;
            public Vector3 valueVector3;
            public Color valueColor;
            public Object valueObject;
        }

        public List<DataPair> dataPairs = new List<DataPair>();

        public bool Contains(string key) {
            if (dataPairs != null) {
                for (int i = 0; i < dataPairs.Count; i++) {
                    var dataPair = dataPairs[i];
                    if (dataPair.key.Trim() == key) {
                        return true;
                    }
                }
            }
            return false;
        }

        public DataPair GetRandom() {
            return dataPairs.Count > 0 ? CommonUtil.RandomList(dataPairs) : null;
        }

        public DataPair GetDataPair(string key) {
            if (dataPairs != null) {
                for (int i = 0; i < dataPairs.Count; i++) {
                    var dataPair = dataPairs[i];
                    if (dataPair.key.Trim() == key) {
                        return dataPair;
                    }
                }
            }
            return null;
        }

        public DataPair GetOrCreateDataPair(string key, ValueType valueType, string comment) {
            DataPair dataPair = GetDataPair(key);
            if (dataPair == null) {
                dataPair = new DataPair() {
                    key = key,
                    valueType = valueType,
                    comment = comment
                };
                dataPairs.Add(dataPair);
            }
            return dataPair;
        }

        public List<DataPair> GetByKeyPrefix(string prefix) {
            List<DataPair> list = new List<DataPair>();
            foreach (DataPair dataPair in dataPairs) {
                if (dataPair.key.Trim().StartsWith(prefix)) {
                    list.Add(dataPair);
                }
            }
            return list;
        }

        public List<DataPair> GetByKeySuffix(string prefix) {
            List<DataPair> list = new List<DataPair>();
            foreach (DataPair dataPair in dataPairs) {
                if (dataPair.key.Trim().EndsWith(prefix)) {
                    list.Add(dataPair);
                }
            }
            return list;
        }

        public void SetComment(string key, string comment) {
            var dataPair = GetDataPair(key);
            if (dataPair != null) {
                dataPair.comment = comment;
            }
        }

        public string GetString(string key, string defaultValue) {
            var dataPair = GetDataPair(key);
            if (dataPair != null) {
                return dataPair.valueString == null ? defaultValue : dataPair.valueString;
            }
            return defaultValue;
        }

        public void SetString(string key, string value) {
            GetOrCreateDataPair(key, ValueType.String, null).valueString = value;
        }

        public bool GetBoolean(string key, bool defaultValue) {
            var dataPair = GetDataPair(key);
            if (dataPair != null) {
                return dataPair.valueBoolean;
            }
            return defaultValue;
        }

        public void SetBoolean(string key, bool value) {
            GetOrCreateDataPair(key, ValueType.Boolean, null).valueBoolean = value;
        }

        public int GetInteger(string key, int defaultValue) {
            var dataPair = GetDataPair(key);
            if (dataPair != null) {
                return dataPair.valueInteger;
            }
            return defaultValue;
        }

        public void SetInteger(string key, int value) {
            GetOrCreateDataPair(key, ValueType.Integer, null).valueInteger = value;
        }

        public float GetFloat(string key, float defaultValue) {
            var dataPair = GetDataPair(key);
            if (dataPair != null) {
                return dataPair.valueFloat;
            }
            return defaultValue;
        }

        public void SetFloat(string key, float value) {
            GetOrCreateDataPair(key, ValueType.Float, null).valueFloat = value;
        }

        public Vector2 GetVector2(string key, Vector2 defaultValue) {
            var dataPair = GetDataPair(key);
            if (dataPair != null) {
                return dataPair.valueVector2;
            }
            return defaultValue;
        }

        public void SetVector2(string key, Vector2 value) {
            GetOrCreateDataPair(key, ValueType.Vector2, null).valueVector2 = value;
        }

        public Vector3 GetVector3(string key, Vector3 defaultValue) {
            var dataPair = GetDataPair(key);
            if (dataPair != null) {
                return dataPair.valueVector3;
            }
            return defaultValue;
        }

        public void SetVector3(string key, Vector3 value) {
            GetOrCreateDataPair(key, ValueType.Vector3, null).valueVector3 = value;
        }

        public Color GetColor(string key, Color defaultValue) {
            var dataPair = GetDataPair(key);
            if (dataPair != null) {
                return dataPair.valueColor;
            }
            return defaultValue;
        }

        public void SetColor(string key, Color value) {
            GetOrCreateDataPair(key, ValueType.Color, null).valueColor = value;
        }

        public Object GetObject(string key) {
            var dataPair = GetDataPair(key);
            if (dataPair != null) {
                return dataPair.valueObject;
            }
            return null;
        }

        public void SetObject(string key, Object value) {
            GetOrCreateDataPair(key, ValueType.Object, null).valueObject = value;
        }

        public GameObject GetGameObject(string key) {
            var dataPair = GetDataPair(key);
            if (dataPair != null) {
                return dataPair.valueObject as GameObject;
            }
            return null;
        }

        public void SetGameObject(string key, GameObject value) {
            GetOrCreateDataPair(key, ValueType.Object, null).valueObject = value;
        }

    }

}
